package cz.muni.fi.pa165.languageschool;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

/**
 * Entity representing Lecturer
 *
 * @author Michal Fučík (395624) michal.fuca.fucik(at)gmail.com
 */
@Entity
@Table(name = "Lecturer")
@XmlRootElement
public class Lecturer extends Person implements Serializable {

    @ElementCollection(fetch = FetchType.EAGER)
    private Set<Language> languages = new HashSet<>();
    @OneToMany(mappedBy = "lecturer", cascade = CascadeType.ALL)
    private List<Lecture> lectures = new ArrayList<>();

    private Language nativeSpeaker;

    // -- Methods --------------------------------------------------------------
    /**
     * Lectures property getter
     *
     * @return
     */
    @XmlTransient
    public List<Lecture> getLectures() {
        return lectures;
    }

    /**
     * Lectures property setter
     *
     * @param lrs
     */
    public void setLectures(Collection<Lecture> lrs) {
        if (lrs != null) {
            lectures = (List<Lecture>) lrs;
        }
    }

    /**
     * Adds Lecture into Lectures list and updates lecture's Lecturer property
     *
     * @param lecture
     */
    public void addLecture(Lecture lecture) {
        if (lecture != null) {
            this.lectures.add(lecture);
            if (lecture.getLecturer() != this) {
                lecture.setLecturer(this);
            }
        }
    }

    /**
     * Languages property getter
     *
     * @return
     */
    public Set<Language> getLanguages() {
        return languages;
    }

    /**
     * Adds language into languages list property
     *
     * @param lan
     */
    public void addLanguage(Language lan) {
        if (lan != null) {
            this.languages.add(lan);
        }
    }

    /**
     * Languages property setter
     *
     * @param ls
     */
    public void setLanguages(Collection<Language> ls) {
        if (ls != null) {
            languages = (Set<Language>) ls;
        }
    }

    /**
     * NativeSpeaker property getter
     *
     * @return native language of Lecturer
     */
    public Language getNativeSpeaker() {
        return nativeSpeaker;
    }

    /**
     * NativeSpeaker property setter
     *
     * @param nativeSpeaker
     */
    public void setNativeSpeaker(Language nativeSpeaker) {
        this.nativeSpeaker = nativeSpeaker;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }

        if (obj == this) {
            return true;
        }

        if (getClass() != obj.getClass()) {
            return false;
        }

        final Lecturer other = (Lecturer) obj;
        if (this.getId() == null || !this.getId().equals(other.getId())) {
            return false;
        }

        return true;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += 13 * (getId() != null ? this.getId().hashCode() : 0);
        hash += 13 * getFirstName().hashCode();
        hash += 13 * getLastName().hashCode();
        return hash;
    }
}
